import cv2 as cv
# 数字表示的是摄像头的编号 0 ： 表示自带摄像头， 1 外接的摄像头
# 手机上 0 前置 1 后置
# 封装resize函数
def resize_img_keep_ratio(img, target_size):
    # img = cv.imread(img_name)  # 读取图片
    old_size = img.shape[0:2]  # 原始图像大小
    ratio = min(float(target_size[i]) / (old_size[i]) for i in range(len(old_size)))  # 计算原始图像宽高与目标图像大小的比例，并取其中的较小值
    new_size = tuple([int(i * ratio) for i in old_size])  # 根据上边求得的比例计算在保持比例前提下得到的图像大小
    img = cv.resize(img, (new_size[1], new_size[0]))  # 根据上边的大小进行放缩
    pad_w = target_size[1] - new_size[1]  # 计算需要填充的像素数目（图像的宽这一维度上）
    pad_h = target_size[0] - new_size[0]  # 计算需要填充的像素数目（图像的高这一维度上）
    top, bottom = pad_h // 2, pad_h - (pad_h // 2)
    left, right = pad_w // 2, pad_w - (pad_w // 2)
    img_new = cv.copyMakeBorder(img, top, bottom, left, right, cv.BORDER_CONSTANT, None, (0, 0, 0))
    return img_new


def cover_face(mask_path='data/mask_green.png',
               camerandex = 0,faceDector_path ="./data/haarcascade_frontalface_default.xml" ,
               yoffset = 0,xoffset = 0,drawBorder = True):
    """

    :param mask_path: 遮盖在脸部的图片，大小内部会自动缩放为合适大小
    :param camerandex: 打开摄像头的索引
    :param faceDector_path: opencv xml 文件路径
    :param y offset: 在 mask y方向上偏移值
    :param x offset: 在 mask x方向上偏移值
    :return:
    """
    video = cv.VideoCapture(camerandex)
    flag = video.isOpened()
    print("摄像头是否打开成功", flag)
    faceDector = cv.CascadeClassifier(faceDector_path)
    # 读取摄像头中的图片信息
    while True:
        # 不停的去读取摄像头的图片信息
        flag, frame = video.read()
        frame = cv.flip(frame, 1)
        mask = cv.imread(mask_path)
        # 获取图片成功
        if flag:
            # 镜像，恢复正常的左右方向
            channels = cv.split(frame)

            # 对每个通道的数据进行直方图均衡化处理
            blue_channel = cv.equalizeHist(channels[0])
            green_channel = cv.equalizeHist(channels[1])
            red_channel = cv.equalizeHist(channels[2])

            # 将3个通道的数据合并成一张彩色的图像
            dst = cv.merge([blue_channel, green_channel, red_channel])

            gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)

            #                         1.输入图像 2. 缩放系数 3.最小检测次数
            faces = faceDector.detectMultiScale(gray, 1.3, 2, minSize=(10, 10));

            # print("检测到人脸数量：", len(faces))
            # [ 79  58 273 273]  x,y, width ,height 人脸的位置
            # print(faces)
            for face in faces:
                x = face[0]
                y = face[1]
                width = face[2]
                height = face[3]
                if drawBorder:
                    cv.rectangle(frame, (x, y), (x + width, y + height), (0, 255, 0), 2)
                shrink = cv.resize(mask, (width, height), interpolation=cv.INTER_AREA)

                for i in range(width):
                    for j in range(height):
                        if (shrink[i][j][0]) > 50 or (shrink[i][j][1]) > 50 or (shrink[i][j][2]) > 50:
                            loc1 = int(y + i - yoffset)
                            loc2 = int(x + j - xoffset)
                            if loc1 > frame.shape[0] or loc2 > frame.shape[1]:
                                continue
                            frame[loc1][loc2] = shrink[i][j]
                cv.imshow("frame ", frame)

        # 1000/2 40  1000/25
        key = cv.waitKey(33)
        # 若用户按了esc就退出了
        if key == 27:
            break

if __name__ == '__main__':

    cover_face(mask_path='data/mask_white.png',drawBorder=False)
